package com.stackalloc;

import org.junit.Test;

/**
 * jvm 参数
 * 不要用 debug 执行
 * -server -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations
 * -server -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:-EliminateAllocations
 * https://www.ibm.com/developerworks/java/library/j-jtp09275/index.html
 *
 * 对象还是在堆上分配。逃逸分析没有违背JVM规范，只是修改了你的代码
 */
public class AllotOnStack {

    public static class User {
        public int id = 0;
        public String name = "";

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public void test() {
        System.out.println("符合栈上分配");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            int alloc = alloc();
            if (alloc > 1)
                System.out.print(alloc);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    public void test2() {
        System.out.println("不符合栈上分配");
        long start = System.currentTimeMillis();
        for (long i = 0; i < 1000000000L; i++) {
            User user = alloc2();
            int alloc = user.getId();
            if (alloc > 1)
                System.out.print(alloc);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    public static void main(String[] args) {
        AllotOnStack allotOnStack = new AllotOnStack();
        allotOnStack.test2();
        allotOnStack.test();
    }

    private static int alloc() {
        User user = new User();
        user.setId(1);
        user.setName("zengxinyao");
        return user.getId();
    }

    private static User alloc2() {
        User user = new User();
        user.setId(1);
        user.setName("zengxinyao");
        return user;
    }
}
